---
hide_table_of_contents: true
---

import CodeBlock from "@theme/CodeBlock";

# Firestore Chat Memory

For longer-term persistence across chat sessions, you can swap out the default in-memory `chatHistory` that backs chat memory classes like `BufferMemory` for a firestore.

## Setup

First, install the Firebase admin package in your project:

```bash npm2yarn
npm install firebase-admin
```

import IntegrationInstallTooltip from "@mdx_components/integration_install_tooltip.mdx";

<IntegrationInstallTooltip></IntegrationInstallTooltip>

```bash npm2yarn
npm install @langchain/openai @langchain/community
```

Visit the `Project Settings` page from your Firebase project and select the `Service accounts` tab.

Inside the `Service accounts` tab, click the `Generate new private key` button inside the `Firebase Admin SDK` section to download a JSON file containing your service account's credentials.

Using the downloaded JSON file, pass in the `projectId`, `privateKey`, and `clientEmail` to the `config` object of the `FirestoreChatMessageHistory` class, like shown below:

```typescript
import { FirestoreChatMessageHistory } from "@langchain/community/stores/message/firestore";
import admin from "firebase-admin";

const messageHistory = new FirestoreChatMessageHistory({
  collections: ["chats"],
  docs: ["user-id"]
  sessionId: "user-id",
  userId: "a@example.com",
  config: {
    projectId: "YOUR-PROJECT-ID",
    credential: admin.credential.cert({
      projectId: "YOUR-PROJECT-ID",
      privateKey:
        "-----BEGIN PRIVATE KEY-----\nCHANGE-ME\n-----END PRIVATE KEY-----\n",
      clientEmail: "CHANGE-ME@CHANGE-ME-TOO.iam.gserviceaccount.com",
    }),
  },
});
```

Here, the `collections` field should match the names and ordering of the `collections` in your database.
The same goes for `docs`, it should match the names and ordering of the `docs` in your database.

## Usage

import Example from "@examples/memory/firestore.ts";

<CodeBlock language="typescript">{Example}</CodeBlock>

### Nested Collections

The `FirestoreChatMessageHistory` class supports nested collections, and dynamic collection/doc names.

The example below shows how to add and retrieve messages from a database with the following structure:

```
/chats/{chat-id}/bots/{bot-id}/messages/{message-id}
```

import NestedExample from "@examples/memory/firestore_nested.ts";

<CodeBlock language="typescript">{NestedExample}</CodeBlock>

## Firestore Rules

If your collection name is "chathistory," you can configure Firestore rules as follows.

```
      match /chathistory/{sessionId} {
       allow read: if request.auth.uid == resource.data.createdBy;
       allow write: if request.auth.uid == request.resource.data.createdBy;
			 }
			 match /chathistory/{sessionId}/messages/{messageId} {
       allow read: if request.auth.uid == resource.data.createdBy;
       allow write: if request.auth.uid == request.resource.data.createdBy;
		    }
```
